package org.robotfish.utils;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

import org.ejml.simple.SimpleMatrix;

public class TableIO {
	public static final String splitSpaces = "\\s+";
	static NumberFormat format = NumberFormat.getInstance(Locale.ENGLISH);
	
	/**
	 * 
	 * @param file
	 * @param splitRegex
	 * @return counts the number of columns and rows
	 * @throws IOException
	 */
	public static int[] countDimensions(String file, String splitRegex) throws IOException {
	    FileInputStream fstream = new FileInputStream(file);
	    DataInputStream in = new DataInputStream(fstream);
	    BufferedReader br = new BufferedReader(new InputStreamReader(in));
	    String data;
	    int rows=0, cols=0;
	    while ((data = br.readLine()) != null)   {
	    	if (data.matches("\\s*")) {
	    		continue;
	    	}
	    	// comment line:
	    	if (data.charAt(0)=='#') {
	    		continue;
	    	}
	    	rows++;
	    	if (cols>0) continue;
	    	// just taking first number of columns:
	    	cols = data.split(splitRegex).length;
	    }
	    
		return new int[]{rows, cols};
	}

	/**
	 * @param file - file name
	 * @return matrix from file, using spaces as column separator
	 * @throws IOException
	 * @throws ParseException
	 */
	public static SimpleMatrix readTable(String file) throws IOException, ParseException {
		return readTable(file, splitSpaces);
	}
	
	/**
	 * @param file - file name
	 * @param splitRegex - regex for splitting columns
	 * @return matrix from file
	 * @throws IOException
	 * @throws ParseException
	 */
	public static SimpleMatrix readTable(String file, String splitRegex) throws IOException, ParseException {
		int[] dim = countDimensions(file, splitRegex);
		SimpleMatrix m = new SimpleMatrix(dim[0], dim[1]);
		
	    FileInputStream fstream = new FileInputStream(file);
	    DataInputStream in = new DataInputStream(fstream);
	    BufferedReader br = new BufferedReader(new InputStreamReader(in));
	    String data;
	    int row = 0, rowFile=0;
	    while ((data = br.readLine()) != null)   {
	    	rowFile++;
	    	// skipping empty rows:
	    	if (data.matches("\\s*")) {
	    		continue;
	    	}
	    	// comment line:
	    	if (data.charAt(0)=='#') {
	    		continue;
	    	}
	    	// splitting and parsing:
	    	String[] x = data.trim().split(splitRegex);
	    	if (x.length != dim[1]) {
	    		throw new RuntimeException(String.format(
	    			"Number of elements in row %d is %d, but should be %d.", 
	    			rowFile, x.length, dim[1]));
	    	}
	    	for (int i=0; i<x.length; i++) {
	    		m.set(row, i, format.parse(x[i].toUpperCase()).doubleValue() );
	    	}
	    	row++;
	    }
	    return m;
	}

}
